From e96f2b5ec14e47119b6b052154c62c2fc281a5b2 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 21 Sep 2005 16:58:55 +0000 Subject: [PATCH] This patch fixes a bug where raise_softirq(SCHEDULE_SOFTIRQ) is called upon a hlt instruction from a VMX guest, causing repeated VMExits when the guest is idle. At the same time, it disables the monitor/mwait feature as it's not feasible to implement for vcpu. Signed-off-by: Xiaofeng Ling Signed-off-by: Asit Mallick Signed-off-by: Jun Nakajima --- xen/arch/x86/vmx.c | 14 ++++---------- xen/arch/x86/vmx_intercept.c | 3 +++ xen/include/asm-x86/vmx_virpit.h | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index bb4d9cf942..c4954ee994 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -471,6 +471,8 @@ static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs *regs) } #endif + /* Unsupportable for virtualised CPUs. */ + clear_bit(X86_FEATURE_MWAIT & 31, &ecx); } regs->eax = (unsigned long) eax; @@ -1461,7 +1463,7 @@ volatile unsigned long do_hlt_count; */ void vmx_vmexit_do_hlt(void) { - raise_softirq(SCHEDULE_SOFTIRQ); + do_block(); } static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs) @@ -1511,12 +1513,6 @@ static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs) } } -volatile unsigned long do_mwait_count; -static inline void vmx_vmexit_do_mwait(void) -{ - raise_softirq(SCHEDULE_SOFTIRQ); -} - #define BUF_SIZ 256 #define MAX_LINE 80 char print_buf[BUF_SIZ]; @@ -1798,9 +1794,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) __update_guest_eip(inst_len); break; case EXIT_REASON_MWAIT_INSTRUCTION: - __get_instruction_length(inst_len); - __update_guest_eip(inst_len); - vmx_vmexit_do_mwait(); + __vmx_bug(®s); break; default: __vmx_bug(®s); /* should not happen */ diff --git a/xen/arch/x86/vmx_intercept.c b/xen/arch/x86/vmx_intercept.c index 1f1494c425..865c51ca30 100644 --- a/xen/arch/x86/vmx_intercept.c +++ b/xen/arch/x86/vmx_intercept.c @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef CONFIG_VMX @@ -205,6 +206,7 @@ static void pit_timer_fn(void *data) /* Set the pending intr bit, and send evtchn notification to myself. */ if (test_and_set_bit(vpit->vector, vpit->intr_bitmap)) vpit->pending_intr_nr++; /* already set, then count the pending intr */ + evtchn_set_pending(vpit->v, iopacket_port(vpit->v->domain)); /* pick up missed timer tick */ if ( missed_ticks > 0 ) { @@ -281,6 +283,7 @@ void vmx_hooks_assist(struct vcpu *d) } vpit->intr_bitmap = intr; + vpit->v = d; vpit->scheduled = NOW() + vpit->period; set_ac_timer(&vpit->pit_timer, vpit->scheduled); diff --git a/xen/include/asm-x86/vmx_virpit.h b/xen/include/asm-x86/vmx_virpit.h index e2a87d26f7..1f80a83f0e 100644 --- a/xen/include/asm-x86/vmx_virpit.h +++ b/xen/include/asm-x86/vmx_virpit.h @@ -35,8 +35,8 @@ struct vmx_virpit_t { unsigned int count; /* the 16 bit channel count */ unsigned int init_val; /* the init value for the counter */ - -} ; + struct vcpu *v; +}; /* to hook the ioreq packet to get the PIT initializaiton info */ extern void vmx_hooks_assist(struct vcpu *d); -- 2.30.2